<?php /* 
==================================================
TextCMS -- simple plain/text CMS with GPL licence
Menu module
(c) 2008, 4X_Pro
Visit us online: http://textcms.ru
==================================================
TODO:
Доделать возможность отдельно задавать уровень для пункта, соответствующего текущему разделу
*/

/** Вывод меню в виде ненумерованного списка
Параметры: $root -- корневой элемент, подуровни которого будут являться пунктами меню
$level -- количество уровней, которое надо выводить
**/
function menu_main($root='/',$level=1) {
  $root=trim($root);
  if ($root!='/' && substr($root,-1,1)!='/') $root.='/'; // добавляем / в конец, если его нет
  if ($root=='./') $root=$GLOBALS['pagedata']['url'];
  $result='';
  $items=menu_build($root,$level);
  $result.=_menu_recursive($items,$root,1,$level);
  return $result;
}

/** Формирование массива со странцами сайта. 
Ключи массива -- родительские элементы, значения -- отсортированные массивы с дочерними элементами
**/
function menu_build($root,$level) {
  $data = menu_pages_get($root,false,true); // выбираем только активные страницы (не удаленные и не черновики)
  $result=array();
  for ($i=0, $count=count($data); $i<$count; $i++) {
    $parent=_menu_parent($data[$i]);
    if ($parent!='/') $parent.='/';
    $result[$parent][]=$data[$i];
  }
  foreach ($result as $key=>$value) usort($result[$root],'_menu_sorter'); //create_function('$a,$b','')
  return $result;
}

/** Рекурсивная обработка массива с элементами для меню для вывода всех уровней до уровня $level
**/
function _menu_recursive($items,$root,$curlevel,$level) {
  $result='';
  if (isset($items[$root]) && is_array($items[$root])) {
    $result='<ul>';
    for ($i=0, $count=count($items[$root]); $i<$count; $i++) {
      $result.='<li><a href="'.cms_hurl($items[$root][$i]['url']).'">'.($items[$root][$i]['title'] ? htmlspecialchars($items[$root][$i]['title']) : 'Безымянная страница').'</a></li>';
      if ($curlevel<$level) $result.=_menu_recursive($items,$items[$root][$i]['url'],$curlevel+1,$level);
    }
    $result.='</ul>';
  }
  return $result;
}

/** Функция для сортировки меню. Вынесена отдельно, а не создается с помощью
create_function, так как при нескольких меню или вложенности более 1 данная функция
вызывается несколько раз подряд, тем самым экономим на производительности. **/
function _menu_sorter($a,$b) {
  return $a["sort"]-$b["sort"];
}

/** Получение списка всех страниц сайта
Параметры -- HURL корня и необходимость включать сам корневой элемент в список **/
function menu_pages_get($parent='/',$include_parent=true,$active=false) {
  $filename=file_exists(cms_basedir().'content.txt') ? cms_basedir().'content.txt' : cms_basedir().'content.def';
  $fh=fopen($filename,'r');
  if (!$fh) {
    trigger_error('Не удалось открыть файл '.$filename.'!',E_USER_WARNING);
    $result=false;
  }  
  else {
    $result=array();
    while ($curitem=fgets($fh)) {
      $data=cms_page_parse(trim($curitem));
      if (menu_is_subelement($parent,$data) && // если дочерний элемент 
        ($include_parent || $data['url']!=$parent) && // или это корневой элемент и включение корневого элемента было запрошено
        (!$active || cms_page_available($data))) // и запрошены только активные элементы (не черновики или черновики с чистовыми версиями)
          $result[]=$data;  
    }
    fclose($fh);
  }
  return $result;
}

/** Получение URL родительского элемента или каталога **/
function _menu_parent($data) {
  if (is_array($data)) $data=$data['url'];
	if (substr($data,-1,1)=='/') $data=substr($data,0,strlen($data)-1);
  $parent=(($pos=strrpos($data,'/'))===0) ? '/' : substr($data,0,$pos);
  return $parent;
}

/** Проверка, является ли элемент дочерним по отношению к указанному URL.
В качестве параметра может приниматься как хеш с данными страницами, так и просто строка 
**/
function menu_is_subelement($root,$element) {
  if (is_array($root)) $root=$root['url'];
  if (is_array($element)) $element=$element['url'];
  if ($root=='/' || strpos($element,$root)===0) return true;
  else return false;
}
